package cn.com.connext.scrm.service;

import cn.com.connext.scrm.domain.enumeration.MemberStatus;
import cn.com.connext.scrm.domain.master.AnswerType;
import cn.com.connext.scrm.domain.master.Member;
import cn.com.connext.scrm.domain.master.Note;
import cn.com.connext.scrm.domain.master.NoteLikes;
import cn.com.connext.scrm.repository.master.*;
import cn.com.connext.scrm.service.dto.InteractiveRecordDTO;
import cn.com.connext.scrm.service.dto.JsonResult;
import cn.com.connext.scrm.service.dto.NoteLikesDTO;
import cn.com.connext.scrm.service.dto.QueryAnswertDTO;
import cn.com.connext.scrm.service.mapper.AnswerTypeService;
import cn.com.connext.scrm.service.mapper.NoteLikesMapper;
import cn.com.connext.scrm.utils.EntityUtils;
import cn.com.connext.scrm.web.rest.AnswerTypeResource;
import cn.com.connext.scrm.web.rest.req.AnswerTypeQueryReq;
import cn.com.connext.scrm.web.rest.req.AnswerLikeCommentReq;
import cn.com.connext.scrm.web.rest.req.AnswerTypeUpdateReq;
import cn.com.connext.scrm.web.rest.resp.QueryAnswerTitleResp;
import cn.com.connext.scrm.web.rest.resp.QueryAnswerTypeResp;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import groovy.util.logging.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.*;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.persistence.criteria.Predicate;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Service
public class AnswerTypeServiceImpl implements AnswerTypeService {
    private final Logger log = LoggerFactory.getLogger(AnswerTypeServiceImpl.class);
    @Autowired
    private AnswerTypeRepository answerTypeRepository;

    @Autowired
    private MemberRepository memberRepository;

    @Autowired
    private NoteLikesRepository noteLikesRepository;

    @Autowired
    private NoteLikesMapper noteLikesMapper;

    @Autowired
    private InteractiveRecordService interactiveRecordService;

    @Autowired
    private NoteRepository noteRepository;

    @Autowired
    private CommentRepository commentRepository;

    @Value("${login.unionid}")
    private String joinId;

    @Transactional
    @Override
    public ResponseEntity<Boolean> saveAnswerType(AnswerType req) {
        answerTypeRepository.save(req);
        return ResponseEntity.ok(true);
    }

    @Override
    public ResponseEntity<Boolean> updateAnswerType(AnswerTypeUpdateReq req) {
        AnswerType answerType = answerTypeRepository.findOne(req.getId());
        answerType.setUpdateTime(new Date());
        answerType.setContent(req.getContent());
        answerType.setPictureUrl(req.getPictureUrl());
        answerType.setTitle(req.getTitle());
        answerTypeRepository.saveAndFlush(answerType);
        return ResponseEntity.ok(true);
    }

    @Override
    public Page answerTypeList(AnswerTypeQueryReq req) {
        int currentPage = (req.getCurrentPage() - 1) < 0 ? 0 : req.getCurrentPage() - 1;
        int pageSize = req.getPageSize() < 1 ? 10 : req.getPageSize();
        Pageable pageable = new PageRequest(currentPage, pageSize, new Sort(Sort.Direction.DESC, "createTime"));
        Specification<AnswerType> specification = (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            if (StringUtils.isNotEmpty(req.getContent())) {
                list.add(criteriaBuilder.like(root.get("content"), "%" + req.getContent() + "%"));
            }
            if (StringUtils.isNotEmpty(req.getTitle())) {
                list.add(criteriaBuilder.like(root.get("title"), "%" + req.getTitle() + "%"));
            }
            list.add(criteriaBuilder.equal(root.get("isDelete"), 0));
            return criteriaBuilder.and(list.toArray(new Predicate[0]));
        };
        Page<AnswerType> page = answerTypeRepository.findAll(specification, pageable);
        List<AnswerType> content = page.getContent();
        if (CollectionUtils.isEmpty(content)) {
            PageImpl<QueryAnswerTypeResp> pageTasks = new PageImpl<>(Collections.emptyList(), pageable, page.getTotalElements());
            return pageTasks;
        }
        List<QueryAnswerTypeResp> queryAnswerTypeResps = EntityUtils.dtoList2PojoList(content, QueryAnswerTypeResp.class);
        queryAnswerTypeResps.stream().forEach(c -> {
            Integer count = noteRepository.countByAnswerType(c.getId());
            c.setTotoleComment(count == null ? new Integer(0) : count);
        });
        List<QueryAnswerTypeResp> result = queryAnswerTypeResps.stream().filter(e -> e.getTotoleComment().compareTo(0) != 0).collect(Collectors.toList());
        return new PageImpl<>(result, pageable, page.getTotalElements());
    }

    @Transactional
    @Override
    public ResponseEntity<Boolean> deleteAnswerType(String id) {
        AnswerType answerType = answerTypeRepository.findOne(id);
        answerType.setIsDelete(1);
        answerType.setUpdateTime(new Date());
        answerTypeRepository.save(answerType);
        return ResponseEntity.ok(true);
    }

    @Override
    public ResponseEntity<List<QueryAnswerTitleResp>> queryAnswerTypeTitle() {
        List<AnswerType> answerTypes = answerTypeRepository.findAll();
        if (CollectionUtils.isEmpty(answerTypes)) {
            return ResponseEntity.ok(Collections.emptyList());
        }
        List<AnswerType> answerTypeList = answerTypes.stream().filter(c -> c.getIsDelete().compareTo(1) != 0).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(answerTypeList)) {
            return ResponseEntity.ok(Collections.emptyList());
        }
        return ResponseEntity.ok(EntityUtils.dtoList2PojoList(answerTypeList, QueryAnswerTitleResp.class));
    }

    @Override
    public JsonResult likeComment(AnswerLikeCommentReq req) {
        String id = req.getId();
        String userId = req.getUserId();
        JsonResult jsonResult = new JsonResult();
        Member member = memberRepository.findOneByUnionId(id);
        if (null == member || member.getStatus() == MemberStatus.DELETED) {
            jsonResult.setState(1);
            jsonResult.setData(null);
            jsonResult.setMessage("当前用户不存在!");
            log.info("评论点赞,当前用户不存在!");
            return jsonResult;
        } else {
            if (true == member.getBanned()) {
                jsonResult.setState(1);
                jsonResult.setData(null);
                jsonResult.setMessage("您已被禁言!");
                log.info("评论点赞,您已被禁言!");
                return jsonResult;
            }
        }
        AnswerType answerType = answerTypeRepository.findOne(id);
        if (null == answerType) {
            jsonResult.setState(1);
            jsonResult.setData(null);
            jsonResult.setMessage("帖子不存在!");
            log.info("评论点赞,帖子不存在!");
            return jsonResult;
        }
        NoteLikes noteLikes = noteLikesRepository.findOneByNoteIdAndUserId(id, userId);
        if (null == noteLikes) {
            NoteLikesDTO noteLikesDTO = new NoteLikesDTO();
            noteLikesDTO.setNoteId(id);
            noteLikesDTO.setUserId(userId);
            noteLikesDTO.setCreateTime(ZonedDateTime.now());
            NoteLikes newNoteLikes = noteLikesMapper.toEntity(noteLikesDTO);
            newNoteLikes = noteLikesRepository.save(newNoteLikes);
            //TODO  点赞需要添加互动记录吗
            InteractiveRecordDTO interactiveRecordDTO = new InteractiveRecordDTO();
            //TODO
            interactiveRecordDTO.setReceiveUserId(joinId);
            interactiveRecordDTO.setNoteId(id);
            interactiveRecordDTO.setCreateTime(newNoteLikes.getCreateTime());
            interactiveRecordDTO.setUserId(userId);
            interactiveRecordDTO.setInteractiveType(2);
            interactiveRecordDTO.setLookup(false);
            interactiveRecordService.createNew(interactiveRecordDTO);
            jsonResult.setState(0);
            jsonResult.setData(newNoteLikes);
            jsonResult.setMessage("点赞成功!");
            return jsonResult;
        } else {
            noteLikesRepository.delete(noteLikes);
            interactiveRecordService.delete(id, userId, joinId, 2);
            jsonResult.setState(0);
            jsonResult.setData(null);
            jsonResult.setMessage("取消点赞成功!");
            return jsonResult;
        }
    }

    /**
     * 数据转换
     */
    private Map<String, Integer> covertt(List<Object[]> content) {
        if (org.apache.commons.collections.CollectionUtils.isEmpty(content)) {
            return Collections.emptyMap();
        }
        Map<String, Integer> result = new HashMap<>();
        content.forEach(c -> {
            List<Object> list = Arrays.asList(c);
            result.put(list.get(0).toString(), Integer.valueOf(list.get(1).toString()));
        });
        return result;
    }
}
